package com.ocr;

import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import com.ocr.*;
import com.dao.ModeDAO;
import com.entity.HistoryItem;
import com.entity.Language;
import com.entity.LanguageContext;
import com.googlecode.tesseract.android.TessBaseAPI;
import com.jabistudio.androidjhlabs.filter.ContrastFilter;
import com.jabistudio.androidjhlabs.filter.DoGFilter;
import com.jabistudio.androidjhlabs.filter.EdgeFilter;
import com.jabistudio.androidjhlabs.filter.GrayscaleFilter;
import com.jabistudio.androidjhlabs.filter.InvertFilter;
import com.jabistudio.androidjhlabs.filter.ReduceNoiseFilter;
import com.jabistudio.androidjhlabs.filter.util.AndroidUtils;
import com.util.CropOption;
import com.util.CropOptionAdapter;
import com.util.OCRCostant;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Bitmap.Config;
import android.media.ExifInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.PopupMenu;
import android.widget.Toast;

public class ImageActivity extends Activity {
	private ImageView imageViewSrc;
	public static Button BTN_SELECTE_LANG;
	private Button btnConvert;
	private ProgressDialog progressDialog;
	private Button btnBack2;
	public static Bitmap PROCESSED_IMG;
	/*
	 * hinh goc chua xu ly anh, chi dung de show len img view null khi anh chua
	 * xu ly
	 */
	public static Bitmap ORGINAL_IMG;
	public static String RESULT_TEXT = "";
	public static Language SELECTED_LANG;
	public static String IMG_PATH;
	private ImageButton btnRotateLeft;
	private ImageButton btnRotateRight;
	private ImageButton btnCrop;
	private ImageButton btnSetting;
	private TessBaseAPI tessBaseAPI = new TessBaseAPI();
	public ModeDAO modeDAO;
	private Context context;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.image_select_activity);
		/*
		 * mode OCR vietnamese, pos =1
		 */
		context = getApplicationContext();
		modeDAO = new ModeDAO(context);
		/*
		 * find view by id
		 */
		imageViewSrc = (ImageView) findViewById(R.id.imageView_src);
		btnConvert = (Button) findViewById(R.id.btn_convert);
		BTN_SELECTE_LANG = (Button) findViewById(R.id.btn_select_language);
		BTN_SELECTE_LANG.setText(LanguageContext.getSelectedLanguage()
				.getName());
		progressDialog = new ProgressDialog(this);
		progressDialog.setCancelable(false);
		progressDialog.setMessage(getResources().getString(
				R.string.message_please_wait));
		progressDialog.setTitle("");
		progressDialog.setIndeterminate(true);
		btnRotateLeft = (ImageButton) findViewById(R.id.btn_rotate_left);
		btnRotateRight = (ImageButton) findViewById(R.id.btn_rotate_right);
		btnBack2 = (Button) findViewById(R.id.btn_back_2);
		btnSetting = (ImageButton) findViewById(R.id.btn_setting);
		btnCrop = (ImageButton) findViewById(R.id.btn_crop);

		SELECTED_LANG = LanguageContext.getSelectedLanguage();// get selected
																// language
		/*
		 * neu đã xu lý ảnh thì phải hiển thị ảnh gốc chứ k hien thị ảnh đã xl
		 */
		if (MainActivity.IMG_BRIGHTNESS_NUM == 1 && ORGINAL_IMG != null)
			imageViewSrc.setImageBitmap(ORGINAL_IMG);
		else
			imageViewSrc.setImageBitmap(PROCESSED_IMG);

		btnConvert.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				if (PROCESSED_IMG != null) {
					ConvertAsyntak convertAsyntak = new ConvertAsyntak();
					convertAsyntak.execute(PROCESSED_IMG);
				} else
					Toast.makeText(getApplicationContext(),
							"Please select an image", Toast.LENGTH_SHORT)
							.show();
			}
		});

		BTN_SELECTE_LANG.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				Intent intent = new Intent(ImageActivity.this,
						SelectLanguageActivity.class);
				startActivity(intent);
			}
		});
		btnBack2.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				onBackPressed();
			}
		});

		btnRotateLeft.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				// khi chỉnh ảnh, nếu ảnh đã xu lý thì phải chỉnh cả ảnh gốc và
				// ảnh đã xl
				if (PROCESSED_IMG != null) {
					int width = PROCESSED_IMG.getWidth();
					int height = PROCESSED_IMG.getHeight();
					Log.d("-------------", "rotate 2");
					width = PROCESSED_IMG.getWidth();
					height = PROCESSED_IMG.getHeight();
					Matrix matrix = new Matrix();
					matrix.postRotate(-90);
					Bitmap scaledBitmap = Bitmap.createScaledBitmap(
							PROCESSED_IMG, width, height, true);
					PROCESSED_IMG = Bitmap.createBitmap(scaledBitmap, 0, 0,
							scaledBitmap.getWidth(), scaledBitmap.getHeight(),
							matrix, true);
					/*
					 * neu da xu ly anh, thi phai quay ca 2 anh
					 */
					if (MainActivity.IMG_BRIGHTNESS_NUM == 1) {
						Bitmap scaledBitmap2 = Bitmap.createScaledBitmap(
								ORGINAL_IMG, width, height, true);
						ORGINAL_IMG = Bitmap.createBitmap(scaledBitmap2, 0, 0,
								scaledBitmap2.getWidth(),
								scaledBitmap2.getHeight(), matrix, true);
						imageViewSrc.setImageBitmap(ORGINAL_IMG);
					} else
						imageViewSrc.setImageBitmap(PROCESSED_IMG);
				}
			}
		});
		btnRotateRight.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				if (PROCESSED_IMG != null) {
					int width = PROCESSED_IMG.getWidth();
					int height = PROCESSED_IMG.getHeight();
					Log.d("-------------", "rotate 2");
					width = PROCESSED_IMG.getWidth();
					height = PROCESSED_IMG.getHeight();
					Matrix matrix = new Matrix();
					matrix.postRotate(90);
					Bitmap scaledBitmap = Bitmap.createScaledBitmap(
							PROCESSED_IMG, width, height, true);
					PROCESSED_IMG = Bitmap.createBitmap(scaledBitmap, 0, 0,
							scaledBitmap.getWidth(), scaledBitmap.getHeight(),
							matrix, true);
					/*
					 * neu da xu ly anh, thi phai quay ca 2 anh
					 */
					if (MainActivity.IMG_BRIGHTNESS_NUM == 1) {
						Bitmap scaledBitmap2 = Bitmap.createScaledBitmap(
								ORGINAL_IMG, width, height, true);
						ORGINAL_IMG = Bitmap.createBitmap(scaledBitmap2, 0, 0,
								scaledBitmap2.getWidth(),
								scaledBitmap2.getHeight(), matrix, true);
						imageViewSrc.setImageBitmap(ORGINAL_IMG);
					} else
						imageViewSrc.setImageBitmap(PROCESSED_IMG);

				}
			}
		});
		btnCrop.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				if (PROCESSED_IMG != null) {
					cropImg();
				}
			}
		});
		btnSetting.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				PopupMenu popup = new PopupMenu(ImageActivity.this, v);
				MenuInflater inflater = popup.getMenuInflater();
				inflater.inflate(R.menu.menu_setting, popup.getMenu());
				/*
				 * load check item
				 */
				try {
					MainActivity.OCR_MODE = modeDAO.readMode();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

				switch (MainActivity.OCR_MODE) {
				case 1:
					popup.getMenu().findItem(R.id.action3_subnormal)
							.setChecked(true);
					break;
				case 2:
					popup.getMenu().findItem(R.id.action3_subquickly)
							.setChecked(true);
					break;
				case 3:
					popup.getMenu().findItem(R.id.action3_subaccurate)
							.setChecked(true);
					break;
				default:
					break;
				}
				/*
				 * action listener
				 */
				popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
					public boolean onMenuItemClick(MenuItem item) {
						Log.d("---------------------OCR",
								"OnMenuItemClickListener");
						switch (item.getItemId()) {

						case R.id.action3_subaccurate:
							MainActivity.OCR_MODE = 3;
							break;
						case R.id.action3_subnormal:
							MainActivity.OCR_MODE = 1;
							break;
						case R.id.action3_subquickly:
							MainActivity.OCR_MODE = 2;
							break;
						default:
							break;
						}
						/*
						 * save new selected mode
						 */
						try {
							modeDAO.saveMode(MainActivity.OCR_MODE);
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						// reload OCR setting
						/*
						 * mode OCR vietnamese, pos =1
						 */
						if (MainActivity.OCR_MODE == 1)
							LanguageContext.changeLanguageCode(1,
									OCRCostant.VIE_PACKCODE_NORMAL);
						else if (MainActivity.OCR_MODE == 2)
							LanguageContext.changeLanguageCode(1,
									OCRCostant.VIE_PACKCODE_QUICKLY);

						else
							LanguageContext.changeLanguageCode(1,
									OCRCostant.VIE_PACKCODE_ACCURATE);

						return true;
					}
				});

				popup.show();// showing popup menu
			}
		});
	}

	private Handler handler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case 0:
				/*
				 * add to recent history
				 */
				Calendar calendar = Calendar.getInstance(new Locale("vie"));
				Date date = new Date(calendar.getTimeInMillis());
				HistoryItem historyItem = new HistoryItem(date,
						ImageActivity.IMG_PATH, ImageActivity.RESULT_TEXT);
				MainActivity.HISTORY_DAO.add(historyItem);
				Intent intent = new Intent(ImageActivity.this,
						ResultActivity.class);
				startActivity(intent);
				break;
			}
		}
	};

	class ConvertAsyntak extends AsyncTask<Bitmap, Void, String> {
		public ConvertAsyntak() {
			// TODO Auto-generated constructor stub

		}

		@Override
		protected void onPreExecute() {
			// TODO Auto-generated method stub
			super.onPreExecute();
			progressDialog.setCancelable(false);
			progressDialog.setIndeterminate(true);
			progressDialog.show();
		}

		@Override
		protected void onPostExecute(String result) {
			// TODO Auto-generated method stub
			super.onPostExecute(result);
			if (progressDialog != null && progressDialog.isShowing())
				progressDialog.dismiss();
			handler.sendMessage(new Message());
		}

		protected String doInBackground(Bitmap... params) {
			// TODO Auto-generated method stub
			try {
				Log.d("------OCRmode now:",
						String.valueOf(MainActivity.OCR_MODE));
				Bitmap bitmap = params[0];
				if (bitmap != null) {
					if (MainActivity.OCR_MODE == 1) {
						tessBaseAPI.init(SELECTED_LANG.getPath(),
								SELECTED_LANG.getLanguageCode(),
								TessBaseAPI.OEM_DEFAULT);
						LanguageContext.changeLanguageCode(1,
								OCRCostant.VIE_PACKCODE_NORMAL);
					} else if (MainActivity.OCR_MODE == 2) {
						tessBaseAPI.init(SELECTED_LANG.getPath(),
								SELECTED_LANG.getLanguageCode(),
								TessBaseAPI.OEM_TESSERACT_ONLY);
						LanguageContext.changeLanguageCode(1,
								OCRCostant.VIE_PACKCODE_QUICKLY);
					} else {
						tessBaseAPI.init(SELECTED_LANG.getPath(),
								SELECTED_LANG.getLanguageCode());
						LanguageContext.changeLanguageCode(1,
								OCRCostant.VIE_PACKCODE_ACCURATE);
					}

					tessBaseAPI.setImage(bitmap);
					RESULT_TEXT = tessBaseAPI.getUTF8Text();
					Log.d("----------result text", RESULT_TEXT);
					tessBaseAPI.end();
				}
				return RESULT_TEXT;
			} catch (Exception ex) {
				AlertDialog.Builder builder1 = new AlertDialog.Builder(
						getApplicationContext());
				builder1.setTitle("Error");
				builder1.setMessage("Your image is too hard to process OCR.");
				builder1.setCancelable(true);
				builder1.setPositiveButton("Yes",
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int id) {
								dialog.cancel();
							}
						});
				builder1.setNegativeButton("No",
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int id) {
								dialog.cancel();
							}
						});
				AlertDialog alertDialog = builder1.create();
				alertDialog.show();
				return null;
			}
		}

	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (resultCode != RESULT_OK)
			return;

		switch (requestCode) {

		case OCRCostant.CROP_FROM_CAMERA:
			Bundle extras = data.getExtras();

			if (extras != null) {
				PROCESSED_IMG = extras.getParcelable("data");

				imageViewSrc.setImageBitmap(PROCESSED_IMG);
			}

			File f = new File(MainActivity.imgUri.getPath());

			if (f.exists())
				f.delete();

			break;
		}
	}

	/*
	 * neu ảnh đã dc xl thì phải crop sẽ trả v�? ảnh chưa duoc xứ lý. Do dùng uri
	 * tới sd card chứ k sử dụng ảnh đã xử lý trong ram -------> sẽ sửa bug bằng
	 * cái ch�?n ảnh xong h�?i ng dùng muốn crop hay k chứ k crop ở giao diện
	 * adjust image.
	 */
	public void cropImg() {
		final ArrayList<CropOption> cropOptions = new ArrayList<CropOption>();

		Intent intent = new Intent("com.android.camera.action.CROP");
		intent.setType("image/*");

		List<ResolveInfo> list = getPackageManager().queryIntentActivities(
				intent, 0);

		int size = list.size();

		if (size == 0) {
			Toast.makeText(this, "Can not find image crop app",
					Toast.LENGTH_SHORT).show();

			return;
		} else {
			intent.setData(MainActivity.imgUri);

			intent.putExtra("outputX", 200);
			intent.putExtra("outputY", 200);
			// intent.putExtra("aspectX", 1);
			// intent.putExtra("aspectY", 1);
			intent.putExtra("scale", true);
			intent.putExtra("return-data", true);

			if (size == 1) {
				Intent i = new Intent(intent);
				ResolveInfo res = list.get(0);

				i.setComponent(new ComponentName(res.activityInfo.packageName,
						res.activityInfo.name));

				startActivityForResult(i, OCRCostant.CROP_FROM_CAMERA);
			} else {
				for (ResolveInfo res : list) {
					final CropOption co = new CropOption();

					co.title = getPackageManager().getApplicationLabel(
							res.activityInfo.applicationInfo);
					co.icon = getPackageManager().getApplicationIcon(
							res.activityInfo.applicationInfo);
					co.appIntent = new Intent(intent);

					co.appIntent
							.setComponent(new ComponentName(
									res.activityInfo.packageName,
									res.activityInfo.name));

					cropOptions.add(co);
				}

				CropOptionAdapter adapter = new CropOptionAdapter(
						getApplicationContext(), cropOptions);

				AlertDialog.Builder builder = new AlertDialog.Builder(this);
				builder.setTitle("Choose Crop App");
				builder.setAdapter(adapter,
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int item) {
								startActivityForResult(
										cropOptions.get(item).appIntent,
										OCRCostant.CROP_FROM_CAMERA);
							}
						});

				builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
					@Override
					public void onCancel(DialogInterface dialog) {

						if (MainActivity.imgUri != null) {
							getContentResolver().delete(MainActivity.imgUri,
									null, null);
							MainActivity.imgUri = null;
						}
					}
				});

				AlertDialog alert = builder.create();

				alert.show();
			}
		}
	}

}
